// to avoid race condition and mix the sessions,
// never send two Ajax request one after another.
// The second Ajax request should be sent when
// the first call response is received
// see http://www.chipmunkninja.com/article/asyncsessions

// if a tag is in, the list is filtered by this tag
var tag_state;
tag_state = new Array;

// remember the timer for the tag selection
var timeo;

// notes window
var noteswin = "";

// keys that do not display the save button
var ignore_keys;
ignore_keys = new Array('9', '16', '17', '18', '27', '35', '36', '39', '37', '38', '40', '116');

/*

This introduce a bug in prototype's Sortable class

Array.prototype.include = function(el) {
    for(var i=0; i<this.length;i++)
        if(this[i]==el) return i;
    return -1;
}

Array.prototype.remove = function(el) {
    for(var i=0; i<this.length;i++) {
        if(this[i]==el) this.splice(i,1);
    }
}

*/


// see http://blog.stevenlevithan.com/archives/faster-trim-javascript
function trim (str) {
	var	str = str.replace(/^\s\s*/, ''),
		ws = /\s/,
		i = str.length;
	while (ws.test(str.charAt(--i)));
	return str.slice(0, i + 1);
}

/*
String.prototype.sanitize = function() {
    for(var i=0; i<this.length;i++) {
        if(this[i]==' ') this[i]='_';
    }
}
*/

function notes(id){
  var win = new Window({
   className: "dialog",
   title: "Notes",
   width:650,
   height:400,
   zIndex: 150,
   url: "/notes/show/" + id,
   showEffectOptions: {duration:1}});
  win.showCenter();
}

function qa_complete() {
  $('qat').value = '';
  }

//var qa = null;

function quick_add(){
  qa = new Window({
   className: "dialog",
   title: "Add a task",
   top:20, left:100,
   width:450,
   height:100,
   zIndex: 150,
   showEffect:Effect.BlindDown,
   hideEffect:Effect.BlindUp,
   showEffectOptions: {duration:0.2},
   hideEffectOptions: {duration:0.2}
   });

  ajax = 'new Ajax.Updater("qa","/task/quick_add",{asynchronous:true, evalScripts:true, parameters:Form.serialize(this), complete:qa_complete(),insertion: Insertion.Top});return false;';
  text = "<form method='post' onsubmit='"+ajax+"'><div><input id='qat' name='t' size=50/> press enter</div></form><ul id='qa' class='mylist'></ul>";
  qa.setHTMLContent(text);
  qa.setStatusBar("Quickly add a new task in your inbox");
  qa.setDestroyOnClose();
  qa.show();
}

function show_qa() {
  quick_add();
  }

function ajax_eval(url) {
  new Ajax.Request(url, {
    asynchronous:true,
    evalScripts:true,
    onComplete: function(r){
      eval(r.responseText);
      }
    });
  }

// remember the id in the session
function cut(id,item_name) {
  str = '/task/cut/'+id+'?item_name='+item_name;
  ajax_eval(str);
  }
  
// paste the element remembered in the session  
function paste(id, item_name) {
  str = '/task/paste/'+id+'?item_name='+item_name;
  ajax_eval(str);
  }
  
function paste_anim(cut_name,paste_name, txt) {
  var c = $(cut_name);
  if(c) c.hide();
  var p = $(paste_name);
  if(p) {
    p.update(txt);
    new Effect.Highlight(p);
    }
  }
  
function set_state(state,id) {
  new Ajax.Updater("task","/inbox/save/"+id+"?s="+state,{asynchronous:true, evalScripts:true});
  }

function expand(task_id,item_name) {
  $('sub_'+item_name+'_'+task_id).show();
  on_click = "collapse('"+task_id+"','"+item_name+"');return false;";
  $('collapse_'+item_name+'_'+task_id).update('<a href="#" onclick="'+on_click+'"><img src="/images/collapse.gif" width=12></a>');
  }


function collapse(task_id,item_name) {
  $('sub_'+item_name+'_'+task_id).hide();
  on_click = "expand('"+task_id+"','"+item_name+"');return false;";
  $('collapse_'+item_name+'_'+task_id).update('<a href="#" onclick="'+on_click+'"><img src="/images/expand.gif" width=12></a>');
  }

// edit a task
function edit(id, item_name) {
    $('e_'+item_name+ '_' + id).src = '/images/loading.gif';
    new Ajax.Request('/task/edit/'+id+'?item_name='+item_name, {
        asynchronous: true,
        evalScripts: true,
        onComplete: function(r){
            $(item_name + '_' + id).update(r.responseText);
        }
    });
}

// add a sub tasks
function add_sub(id, item_name) {
    $('a_'+item_name+'_'+ id).src = '/images/loading.gif';
    new Ajax.Request('/task/add_sub/' + id, {
        asynchronous: true,
        evalScripts: true,
        onComplete: function(r){
            new Insertion.Top('sub_'+item_name+'_'+id, r.responseText);
            $('a_'+item_name+'_'+ id).src = '/images/add.png';
        }
    });
  }

// TODO
function demote(id){
    var el = $('loading');
    el.src = '/images/loading.gif';
    new Ajax.Request('/task/demote/' + id, {
        asynchronous: true,
        evalScripts: true,
        parameters: Sortable.serialize('taskslist'),
        onComplete: function(r){
            $('taskslist').update(r.responseText);
            recreate_sortable('taskslist');
        }
    });
    return false;
}

function unselect_all_tag()   {
  for(i=tag_state.length-1;i>=0;i--) {
    tag = tag_state[i];
    toggle_tag_state(tag);
    update_tag_display(tag);
    }
  }
  
function disp_sub(id){
    if(!$('taskcontent')) {alert('This function is not available right now');return false};
    if(id!=0 && (el = $('ds'+id))) el.src='/images/loading.gif';
    unselect_all_tag();
    new Ajax.Request('/task/disp_sub/' + id, {
        asynchronous: true,
        evalScripts: true,
        onComplete: function(r){
            $('taskcontent').update(r.responseText);
            recreate_sortable('taskslist');
        }
    });
    return false;
}

function disp_del_task(id, item_name){
  if (id == '-1') {alert('Error: Task not found');return;}
  else if (id == '-2') {alert('Error: Task can not be deleted');return;}
  else if(String(id) != String(parseInt(id))) {alert('Error: '+String(id));return;}
  new Effect.BlindUp($(item_name+'_'+id));
  }

function del(id, item_name){
  if (confirm('Delete this task and all subtasks ?\n\"' + $('t' + id).value + '\"')) {
      var el = $('de_'+item_name+'_'+id);
      el.src = '/images/loading.gif';
      new Ajax.Request('/task/delete/'+id, {
          onComplete: function(r){
            disp_del_task(r.responseText, item_name);
          }
      });
  }
  return false;
}

// update the task's deadline div
function update_task_deadline(task_id, deadline){
  var el = $('deadline' + task_id);
  el.innerHTML = deadline;
}

// update the task's tags div
function update_task_tags(task_id, tags){
  var el = $('tag' + task_id);
  el.innerHTML = tags;
}

// display all project tags
function display_tags(str) {
  var el = $('tags');
  if(!el) return;
  el.update(str);
  update_all_tag_display();
}

// as js string's size can not > 1024
function expand_tags(str, path, pid) {
  var el = $('tags');
  if(!el) return;
  if(pid=='') {alert('no project id in expand_tags');return;}
  rv = '';  
  tags = str.split('|');
  for(var i=0; i < tags.length;i++) {
    t = trim(tags[i]);
    if(t=='') continue;
    rv += '<div id="tag_filter_'+t+'" class="tag" onclick="toggle_tag(\''+path+'\','+pid+',\''+t+'\')">'+t+'</div> ';
    }
  el.update(rv);
  update_all_tag_display();
  }

// update the display by filtering by tags
function filter_tasks(controller,project_id,tags) {
  $('loading').src = '/images/loading.gif';
  new Ajax.Request('/'+controller+'/filter_by_tag/' + project_id + '?t=' + tags, {
      asynchronous: true,
      evalScripts: true,
      onComplete: function(request){
        display_tasks(request.responseText);
      }});
}

function update_tag_display(tag) {
  var el = $('tag_filter_' + tag);
  if(!el) return; // happens when the last task with this tag has been done
  if(tag_state.indexOf(tag)==-1)
      el.className = 'tag';
  else
      el.className = 'tag on';
}

function toggle_tag_state(tag) {
  if(tag_state.indexOf(tag)==-1)
      tag_state.push(tag);
  else
      tag_state = tag_state.without(tag);
}

// update tag_state's tag display
function update_all_tag_display() {
  tag_state._each(update_tag_display)
}

// filter by tag
function toggle_tag(controller,project_id, tag) {
    // change style
    clearTimeout(timeo);
    var el = $('loading')
    el.src = '/images/icon_clock.gif';
    el.show();
    toggle_tag_state(tag);
    update_tag_display(tag);
    timeo = setTimeout("filter_tasks('"+controller+"',"+project_id+", '"+tag_state.join(',')+"')",1000);
}

// done     : is the task done ?
// done_diff: did the done status changed ?
function saved(id, item_name, txt, done, done_diff) {
  //if(!item_name) alert('item_name not defined')

  //var el = $('s' + id);
  //new Effect.Fade(el);

  var el = $(item_name+'_'+id);
  if(!el) {alert('no item named '+item_name+'_'+id);return;}
  el.update(txt);
  
//    TODO: all was commented out because of the new hierarchy system
//    var to;
//    if (done) {
//        to = $('taskdoneul');
//        if(done_diff) {
        //$('done_on_'+id).content("done just now");
        // if we done the last task tagged and if this tag was in the tag state,
        // then it will never be removed from the tag state
        // so we clear it now
        // TODO: check if this task was the last task with this tag
//          tag_state.clear();
//          }
//        }
//    else  {
//        to = $('taskslist');
        //if(done_diff) $('done_on_'+id).content("undone");
//        }
//    if (el.parentNode != to) 
//        to.insertBefore(el, to.firstChild);
  mover('');
  new Effect.Highlight(el);
  return false;
}

function save(id, item_name, createproject){
  if (String(createproject) == "undefined") 
      createproject = 0;
  //if ($('p' + id).value == '') {
  //   alert('You must assign this task to a project. Type the name of the project this task belongs to in the first field. If the project does not exists, it will be created.');
  //    return false;
  //}
  var el = $('s' + id);
  el.src = '/images/loading.gif';
  new Ajax.Request('/task/save/'+id+'?item_name='+item_name, {
      asynchronous: true,
      evalScripts: true,
      onComplete: function(r){
          eval(r.responseText)
      },
      parameters: Form.serialize(item_name+'_'+id) + "&C=" + createproject
  });
  return false;
  }

function setclass(c, i){
    $('p' + i).className = c;
    $('t' + i).className = c;
    $('r' + i).className = c;
    $('pr' + i).className = c;
    $('da' + i).className = c;
}


function change(i, event){
    event = event || window.event;
    if(event != null) {
        event.preventDefault();
        var key = event.keyCode;
        //alert(key);
        if(ignore_keys.indexOf(key)!=-1) 
          return true;
        //if(key == '13')
        //  save(i,0);
        if(event.ctrlKey && (key == '67')) 
          return true; // Ctr-C
        if(event.ctrlKey && (key == '65')) 
          return true; // Ctr-A
        if (event.ctrlKey && (key == '83')) {
          save(i);
          return false;
          } // Ctr-S, does not work...
        }
    // change style if done
    el = $('d' + i);
    if(!el) return false; //  return now if there is no done checkbox
    if (el.checked) setclass('done', i);
    else            setclass('', i);
    return false;
}

function recreate_sortable(el){
  //Sortable.destroy(el);
  Sortable.create(el, {
    onUpdate: function(){
      new Ajax.Request('/task/order', {
        asynchronous: true,
        evalScripts: true,
        parameters: Sortable.serialize(el)
        });
      }
    });
  }

function displaynew(id, str){
  Element.hide('loading');
  new Insertion.Top('taskslist', str);
  if(!$('taskslist').visible()) {
    $('deadlines').toggle();
    $('taskslist').toggle();
    }
  recreate_sortable('taskslist');
  $('t' + id).focus();
  return false;
  }

function add_new_row(){
    Element.show('loading');
    new Ajax.Request('/task/createnew', {
        asynchronous: true,
        evalScripts: true,
        onComplete: function(request){
            eval(request.responseText);
        }
    });
    return false;
}

function display_tasks(str){
    $('taskcontent').update(str);
    //if(tag_state.length > 0) // not sortable if the list is filtered by a tag
    //  Sortable.destroy('taskslist'); // Sortable.destroy does not work, was not documented....
}

/*
function ajax_show_project_resp(str) {
  new Ajax.Request('/task/show_project_resp/' + str, {
      asynchronous: true,
      evalScripts: true,
      onComplete: function(request){
          $('members').update(request.responseText);
      }
  });
}
*/

function ajax_select_project(str) {
  new Ajax.Request('/task/select_project/' + str, {
      asynchronous: true,
      evalScripts: true,
      onComplete: function(r){
          eval(r.responseText);
      }
  });
}

function select_project(str){
    if (str == "") return;
    $('loading').show();
    tag_state.clear();
    ajax_select_project(str);      
    return false;
}

function select_resp(str){
    if (str == "") return;
    $('loading').show();
    new Ajax.Request('/task/select_resp/' + str, {
        asynchronous: true,
        evalScripts: true,
        onComplete: function(r){
            eval(r.responseText);
        }
    });
    return false;
}

function select_state(str){
    if (str == "") return;
    $('loading').show();
    new Ajax.Request('/task/select_state/' + str, {
        asynchronous: true,
        evalScripts: true,
        onComplete: function(r){
            eval(r.responseText);
        }
    });
    return false;
}



//Mouse over task's element
function mover(e, add){
    if (String(add) == "undefined") 
        add = "";
    if (add != "") 
        add = "<br/><br/><span>" + add + "</span>";
    switch (e) {
        case '':
        $('info').innerHTML = "" + add;
        break;
        case 'd':
        $('info').update("Click to indicate that this task is done" + add);
        break;
        case 'p':
        $('info').innerHTML = "Name of the project this task belongs to" + add;
        break;
        case 't':
        $('info').innerHTML = "Title of the task to do" + add;
        break;
        case 'r':
        $('info').innerHTML = "Responsible of this task" + add;
        break;
        case 'pr':
        $('info').innerHTML = "Priority of this task (number)" + add;
        break;
        case 's':
        $('info').innerHTML = "Save changes" + add;
        break;
        case 'de':
        $('info').innerHTML = "Delete permanently this task" + add;
        break;
        case 'a':
        $('info').innerHTML = "Add a new task" + add;
        break;
        case 'n':
        $('info').innerHTML = "Edit notes";
        break;
        case 'da':
        $('info').innerHTML = "Task\'s due date";
        break;
        default:
        $('info').innerHTML = "no help for " + e;
        break;
    }
}

function create_project_confirm(taskid){
    saveimg = $('s' + taskid);
    saveimg.src = '/images/save.png';
    var str = "This project does not exist.\nDo you want to create the project named '" + $('p' + taskid).value + "' ?";
    if (confirm(str)) 
        save(taskid, 1);
}

var calid;
function dispcal2(cal){
    change(calid, null);
}

function dispcal(id, value){
    calid = id;
    Calendar.setup({
        inputField: "da" + id,
        ifFormat: "%Y-%m-%d",
        showsTime: false,
        onUpdate: dispcal2
    });
}

function star_it(id) {
  new Ajax.Request('/task/star_it/' + id, {
      asynchronous: true,
      evalScripts: true,
      onComplete: function(r){
        eval(r.responseText)
      }
    });
}

function star(taskid, value){
    img = $('st' + taskid);
    switch (value) {
        case 1:
        str = 'on';
        break;
        default:
        str = 'off';
        break;
    }
    img.src = '/images/star_' + str + '_2.gif';
}
function sort_by_priority() {
  new Ajax.Request('/task/sort_by_priority/?t=' + tag_state.join(','), {
      asynchronous: true,
      evalScripts: true,
      onLoading: $('loading').show(),
      onComplete: function(r){
        $('taskcontent').update(r.responseText);
      }
    });

}

